/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	ComponentReflection.cpp
*
*	Comments	-	See ComponentReflection.h
*
**************************************************************************************/
#include "../Include/ComponentReflection.h"
#include "../Include/Actor.h"

#include "../Include/ComponentModelRenderer.h"
#include "../Include/ComponentCamera.h"

#include "../Include/EventRender.h"

#include "../Include/RenderEntryBindParameters.h"

namespace Pulse
{
	ComponentReflection::ComponentReflection( Actor *pOwner )
		: IComponent( pOwner )
	{

	}

	ComponentReflection::~ComponentReflection( void )
	{
		m_pOwner->RemoveListener( EEvent::MODEL_LOADED, this, &ComponentReflection::OnModelLoaded );
		m_pOwner->RemoveListener( EEvent::MODEL_UNLOAD, this, &ComponentReflection::OnModelUnloaded );
		m_pOwner->RemoveListener( EEvent::RENDER, this, &ComponentReflection::OnRender );
		//m_pOwner->RemoveListener( EEvent::TRANSFORM, this, &ComponentReflection::OnTransform );
	}

	EErrorCode::Type ComponentReflection::Initialize( XMLElementPtr pElem )
	{
		// This can only exist if we have a model renderer
		// We should probably have a componentModelFileter

		m_pOwnerRenderer = (ComponentModelRenderer*)m_pOwner->GetComponent( EComponent::RENDERER );

		return EErrorCode::OKAY;
	}

	void ComponentReflection::Update( FLOAT dt )
	{
		// Check for each camera reflection setting and see when was it last used.
		// Then remove settings that hasn't been used for a certain set time.
		const FLOAT loopFrequency = 1.0f /* / 1.0f */;	// Update loops only every given time
		const FLOAT camParamsTimeLimit = 8.0f;	// Delete settings if not used more than given time

		// TODO: We can make this perform once every x amount of time
		{
			CamRefSettingList::Iterator iter = m_camRefList.IteratorBegin();
			CamRefSettingList::Iterator iterEnd = m_camRefList.IteratorEnd();

			while ( iter != iterEnd )
			{
				// TODO: Last time used...
				++iter;
			}
		}

	}

	void ComponentReflection::OnRender( IEvent *pEvent )
	{
		// TODO: Handle reflection processing here...
		EventRender *pRenderEvent = (EventRender*)pEvent;
		ComponentCamera *pCamera = pRenderEvent->GetCamera();
		RenderView *pView = pRenderEvent->GetRenderView();
		
		// Find if we have a record of the camera
		CameraReflectionSetting *pSetting = m_camRefList[pCamera];
		
		// Create setting if not available
		if ( pSetting == PSX_NULL )
		{
			//CameraReflectionSetting *pNewSettings = new CameraReflectionSetting;
			//
			//pNewSettings->m_pCamActor = pCamera->GetOwnerUnsafe(); // We're only using this as a key so that's okay
			////pNewSettings->
			//pNewSettings->m_pRendererBinderReference = m_pOwnerRenderer->GetCameraSpecificParameters( pCamera );

			//m_camRefList[pCamera] = pNewSettings;
		}




		//pBinders->FindParameterBinder(  );

		//// Texture creation
		//if ( pMat->IsMaterialElementAvailable( pMatElem->m_type, pMatElem->m_name.GetBuffer() ) == FALSE )
		//{


		//	//const SIZE_T textureReflectionSize = 512; // TODO: Set this in graphics/engine configuration script.
		//	//GraphicsResourceManager *pGM = GraphicsResourceManager::GetInstance();
		//	//Texture2DDesc desc;
		//	//Texture2D *pTexture;

		//	//desc.SetAsRenderTarget( textureReflectionSize, textureReflectionSize );
		//	//pTexture = pGM->CreateTexture2D( &desc );

		//	//EErrorCode::Type retCode = pMat->AddParameter( GFX_PARAM_TEXTURE_PLANAR_REFLECTION, pTexture );

		//	//if ( retCode != EErrorCode::OKAY )
		//	//{
		//	//	PSX_PushError( "Failed to add reflection texture." );
		//	//}

		//}
		//else
		//{
		//	// TODO: We need to handle this types of error as gracefully as possible.
		//	PSX_PushError( "Planar reflection texture already exists." );
		//}
	}

	void ComponentReflection::OnTransform( IEvent *pEvent )
	{

	}

	void ComponentReflection::OnModelLoaded( IEvent *pEvent )
	{

	}

	void ComponentReflection::OnModelUnloaded( IEvent *pEvent )
	{

	}
}